package com.ifcar.app.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.ifcar.app.rss.GetColumnsInfo;
import com.ifcar.app.service.PushService;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.HttpStatus;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

public class HttpUtils {
	 
    
    /**
     * 获取图片短地址URL
     * @param orgimgurl
     * @param mContext
     * @return String
     */
	public static String getImageShortUrl(String orgimgurl,Context mContext){
		
		String rst = "";
		rst = getResponseFromGetUrl(GetColumnsInfo.Img_shorturl+orgimgurl+".html",10000,mContext);
		JSONObject jsonobj = Tools.StringToJson(rst);
		
		if(null!=jsonobj){
			try {
				rst = jsonobj.getString("shortURL");
			} catch (JSONException e) {
				rst = orgimgurl;
			}
			
		}else{
			rst = orgimgurl;
		}
		return rst;
	}
	
	/**
	 * 获取文章短地址
	 * @param _3wor3g
	 * @param orgimgurl
	 * @param mContext
	 * @return
	 */
	public static String getDocShortUrl(String _3wor3g,String orgimgurl,Context mContext){
		
		String rst = "";
		rst = getResponseFromGetUrl(GetColumnsInfo.Article_shorturl+_3wor3g+"/"+orgimgurl+".html",10000,mContext);
		JSONObject jsonobj = Tools.StringToJson(rst);
		
		if(null!=jsonobj){
			try {
				rst = jsonobj.getString("shortURL");
			} catch (JSONException e) {
				rst = orgimgurl;
			}
			
		}else{
			rst = orgimgurl;
		}
		return rst;
	}
	
	/**
	 * post上传文件
	 * @param actionUrl
	 * @param params
	 * @param files
	 * @param cookie
	 * @return
	 * @throws IOException
	 */
	public static String post(String actionUrl, Map<String, String> params,
			FormFile[] files, String cookie) throws IOException {

		String twoHyphens = "--";
		String BOUNDARY = "******";
		String MULTIPART_FROM_DATA = "multipart/form-data";

		URL uri = new URL(actionUrl);
		HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
		conn.setReadTimeout(5 * 1000); // 缓存的最长时间
		conn.setDoInput(true);// 允许输入
		conn.setDoOutput(true);// 允许输出
		conn.setUseCaches(false); // 不允许使用缓存
		// 下面的几个值是必须需要设置进去的
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Connection", "keep-alive");
		conn.setRequestProperty("Charsert", "UTF-8");
		conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
				+ "; boundary=" + BOUNDARY);
		conn.setRequestProperty("Cookie", cookie);
		// 首先组拼文本类型的参数
		StringBuilder sb = new StringBuilder();

		// 这个地方使用了Map循环 map循环的方式需要注意一下了
		for (Map.Entry<String, String> entry : params.entrySet()) {

			sb.append(twoHyphens + BOUNDARY);
			// 回车换行
			sb.append("\r\n");
			sb.append("Content-Disposition: form-data; name=\""
					+ entry.getKey() + "\"" + "\r\n\r\n");
			sb.append(entry.getValue());
			sb.append("\r\n");

		}
		DataOutputStream outStream = new DataOutputStream(
				conn.getOutputStream());
		outStream.write(sb.toString().getBytes());

		// 前面必须是数组才可以
		// 发送文件数据
		for (FormFile file : files) {

			StringBuilder sb1 = new StringBuilder();

			sb1.append(twoHyphens + BOUNDARY);
			sb1.append("\r\n");
			// 这个地方没有完
			sb1.append("Content-Disposition: form-data; name=\""
					+ file.getFormnames() + "\"; filename=\""
					+ file.getFileName() + "\"" + "\r\n");
			sb1.append("Content-Type: " + file.getContentType() + "\r\n\r\n");
			outStream.write(sb1.toString().getBytes());

			// 先判断formfile里面是否为空 如果不为空的话则写出 获取formfile的data里面的
			if (file.getInStream() != null) {
				// 提供流的的方式的话就是一边读一边写了
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = file.getInStream().read(buffer)) != -1) {
					outStream.write(buffer, 0, len);
				}
				file.getInStream().close();
			} else {
				outStream.write(file.getData(), 0, file.getData().length);

			}
			outStream.write("\r\n".getBytes());

		}
		byte[] end_data = (twoHyphens + BOUNDARY + twoHyphens + "\r\n")
				.getBytes();
		outStream.write(end_data);
		outStream.flush();

		// 得到响应号码
		int res = conn.getResponseCode();
		if (res != 200)
			throw new RuntimeException("请求失败 ");
		InputStream in = conn.getInputStream();
		int ch;
		StringBuilder sb2 = new StringBuilder();
		while ((ch = in.read()) != -1) {
			sb2.append((char) ch);
		}
		outStream.close();
		conn.disconnect();
		return sb2.toString();
	}

	public static String getResponseFromGetUrl(String url, int timeout,Context mContext) {
	    return getResponseFromGetWithRetry(url,timeout,mContext);
	}
	
	/**
	 * GBK编码
	 * @param url
	 * @param timeout
	 * @param mContext
	 * @return
	 */
	public static String getResponseFromGetUrl4GBK(String url, int timeout, Context mContext) {
		HttpGet httpGet = new HttpGet(url);
		DefaultHttpClient httpclient = null;
		String resultString = null;
		
		try {
			
			HttpParams httpParameters = new BasicHttpParams(); 
			int timeoutConnection = timeout; 
			HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);  
			int timeoutSocket = timeout; 
			HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 
			HttpProtocolParams.setUserAgent(httpParameters, StringUtil.userAgent);
			httpclient = new DefaultHttpClient(httpParameters); 
			
			Tools.setHttpClientHostProxy(httpclient, mContext);
			
			HttpResponse response = httpclient.execute(httpGet);
			
			if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
				resultString = EntityUtils.toString(response.getEntity(),"GBK");
			
		} catch (Exception e) {
			resultString = null;
			e.printStackTrace();
		}finally{
		    if(null!=httpclient){
		        httpclient.getConnectionManager().shutdown();
		    }
		}
		
		return resultString;
	}
	
	/**
	 * 获取Push数据
	 * @param url
	 * @param timeout
	 * @param mContext
	 * @return
	 */
	public static String getResponseFromGetUrlForPUSH(String url, int timeout,Context mContext,SharedPreferences mSP) {
		StringBuffer sb = new StringBuffer();
		String inputLine = "";
		DefaultHttpClient httpclient = null;
		try {
			
			HttpParams httpParameters = new BasicHttpParams(); 
			int timeoutConnection = timeout; 
			HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);  
			int timeoutSocket = timeout; 
			HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 
			HttpProtocolParams.setUserAgent(httpParameters, StringUtil.userAgent);
			
			httpclient = new DefaultHttpClient(httpParameters);
			Tools.setHttpClientHostProxy(httpclient, mContext);
			
			HttpGet httpRequest = new HttpGet(url);
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			
			int interval = getX_PollFromHead(httpResponse);
			if(null==mSP){
			    mSP = PreferenceManager.getDefaultSharedPreferences(mContext);
			}
			mSP.edit().putInt(PushService.INTERVAL_TAG,interval).commit();
			
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			if (statusCode == HttpStatus.SC_OK) {

				InputStreamReader is = new InputStreamReader(httpResponse
						.getEntity().getContent());
				BufferedReader in = new BufferedReader(is);
				while ((inputLine = in.readLine()) != null) {

					sb.append(inputLine);
				}

				in.close();

			}else if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
			    sb.append("304");
			}else{
				sb.append("error");
			}
		} catch (Exception e) {
			sb.append("error");
		} finally {
			if(null!=httpclient){
				httpclient.getConnectionManager().shutdown();
			}
			
		}
		return sb.toString();
	}
	
	private static int getX_PollFromHead(HttpResponse httpResponse){
	    
	    int defaultInterval = 2 * 60 * 1000;
	    if(null!=httpResponse){
	       Header head = httpResponse.getLastHeader("X-Poll");
	       if(null!=head){
	           
    	        try {
                   int  poll = new Integer(head.getValue()).intValue();
                    if(poll<60){
                        defaultInterval = 60 * 1000;
                    }else if(poll>600){
                        defaultInterval = 600 * 1000;
                    }else{
                        defaultInterval = poll * 1000;
                    }
                } catch (Exception e) {
                   
                }
	       }
	    }
	 
	    return defaultInterval;
	}
	
    
	/**
	 * Post 请求
	 * @param params
	 * @param url
	 * @param mContext
	 * @return
	 */
	public static String getResponseFromPostUrl(List<NameValuePair> params, String url,Context mContext) {
		String result = "";
		HttpPost httpRequest = new HttpPost(url);
		httpRequest.setHeader("referer", "http://www.163.com");
		DefaultHttpClient httpclient = new DefaultHttpClient();
		Tools.setHttpClientHostProxy(httpclient, mContext);
		if(null==params){
			params = new ArrayList<NameValuePair>();
		}
		try {
			httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
			httpRequest.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,false);
			HttpResponse response = httpclient.execute(httpRequest);
			if (response.getStatusLine().getStatusCode() == 200) {
				result = EntityUtils.toString(response.getEntity());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
		return result;
	}
	/**
     * Post Push请求
     * @param params
     * @param url
     * @param mContext
     * @return
     */
	public static String getResponseFromPostUrlForPUSH(List<NameValuePair> params, String url,Context mContext) {
		String result = "";
		
		HttpParams httpParameters = new BasicHttpParams(); 
		HttpProtocolParams.setUserAgent(httpParameters, StringUtil.userAgent);
		DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters);
		Tools.setHttpClientHostProxy(httpclient, mContext);
		try {
			HttpPost request = new HttpPost(url);
			if(params != null) request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));			
			HttpResponse response = httpclient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				result = EntityUtils.toString(response.getEntity());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
		return result;
	}
	
	/**
	 * 具有重试机制的httpget请求
	 * @param url
	 * @param timeout
	 * @param mContext
	 * @return
	 */
	public static String getResponseFromGetWithRetry(String url,int timeout,Context mContext) {
        String responseString = "";
        DefaultHttpClient httpclient = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            HttpParams httpParams = new BasicHttpParams();
            //设置连接超时和数据读取超时
            HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
            HttpConnectionParams.setSoTimeout(httpParams, timeout);
            HttpProtocolParams.setUserAgent(httpParams, StringUtil.userAgent);
            //获取HttpClient
            httpclient = NeteaseHttpClient.getHttpClient(httpParams);
            Tools.setHttpClientHostProxy(httpclient, mContext);
            NeteaseHttpClient.initCache(mContext);
            responseString = NeteaseHttpClient.getforCache(httpGet);
            
        } catch (Exception e) {
            
        } finally {
           
            
        }
        
        return responseString;
    }

    
}
